#ifndef __CO_COUNTER_H__
#define __CO_COUNTER_H__

#include <vector>
#include "common/record_counter.h"

/*
struct CoFdReactorCounter
{
	long epoll_handle_fd_counter;

	long epoll_set_counter;
	long epoll_set_cost_counter;	// us

    long epoll_notify_write_counter;
    long epoll_notify_write_full_counter;
    long epoll_notify_write_cost_counter;   // us

	long epoll_wait_counter;
	long epoll_wait_cost_counter;	// us
	vector<long> epoll_wait_timeout_counters;
};

struct CoScheduleCounter
{
	int  pid;
	int  running_id;

	long switch_counter;
	long switch_wait_counter;
	long switch_wait_cost_counter; // ms
};
*/

class CoFdReactorCounter : public StoreCounter<CoFdReactorCounter, 12>
{
public:
    enum {
        EPOLL_HANDLE_FD_COUNTER = 0,
        
        EPOLL_MOD_COUNTER,
        EPOLL_MOD_COST_COUNTER,

        EPOLL_ADD_COUNTER,
        EPOLL_ADD_COST_COUNTER,

        EPOLL_DEL_COUNTER,
        EPOLL_DEL_COST_COUNTER,
        
        EPOLL_WAIT_COUNTER,
        EPOLL_WAIT_COST_COUNTER,
    };

    void convert() {

        epoll_handle_fd_counter = _counters[EPOLL_HANDLE_FD_COUNTER];

        epoll_mod_counter = _counters[EPOLL_MOD_COUNTER];
        epoll_mod_cost_counter = _counters[EPOLL_MOD_COST_COUNTER];

        epoll_add_counter = _counters[EPOLL_ADD_COUNTER];
        epoll_add_cost_counter = _counters[EPOLL_ADD_COST_COUNTER];

        epoll_del_counter = _counters[EPOLL_DEL_COUNTER];
        epoll_del_cost_counter = _counters[EPOLL_DEL_COST_COUNTER];

        epoll_wait_counter = _counters[EPOLL_WAIT_COUNTER];
        epoll_wait_cost_counter = _counters[EPOLL_WAIT_COST_COUNTER];
    }
    
public:
    long epoll_handle_fd_counter;
    
    long epoll_mod_counter;
    long epoll_mod_cost_counter;

    long epoll_add_counter;
    long epoll_add_cost_counter;

    long epoll_del_counter;
    long epoll_del_cost_counter;

    long epoll_wait_counter;
    long epoll_wait_cost_counter;
};

class CoScheduleCounter : public StoreCounter<CoScheduleCounter, 3>
{
public:
    enum {
        SWITCH_COUNTER = 0,
        SWITCH_WAIT_COUNTER,
        SWITCH_WAIT_COST_COUNTER,
    };
    
    void convert() {
        switch_counter = _counters[SWITCH_COUNTER];
        switch_wait_counter = _counters[SWITCH_WAIT_COUNTER];
        switch_wait_cost_counter = _counters[SWITCH_WAIT_COST_COUNTER] / 1000;
    }
    
public:
    long switch_counter;
    long switch_wait_counter;
    long switch_wait_cost_counter;
};

struct CoStatics
{
	long total_switch_counter;
	long total_switch_wait_counter;
	long total_switch_wait_cost_counter; // ms

	std::vector<CoScheduleCounter> schedule_counters;

	CoFdReactorCounter reactor_counter;

	int	co_count;
	int co_ready_count;
	int co_suspend_count;
};

#endif

